const fs = require('fs')
console.log(fs.stat())
const EventEmitter = require('events')

class MyFileReadStream extends EventEmitter {
    constructor(path, options = {}) {
        super()
        this.path = path
        this.flags = options.flags || 'r'
        this.mode = options.mode || 438
        this.autoCLose = options.autoClose || true
        this.start = options.start || 0
        this.end = options.end
        this.highWaterMark = options.highWaterMark || 64 * 1024
        this.readOffset = 0
        this.open()
        this.on('newListener', (type) => {
            // console.log('type :>> ', type);
            if (type === 'data') {
                this.read()
            }
        })
    }

    open() {
        // 原生的open方法
        // console.log('111:', 111);

        fs.open(this.path, this.flags, this.mode, (err, fd) => {
            if (err) {
                this.emit('error', err)
            }
            this.fd = fd
            this.emit('open', fd)
        })
    }
    read() {
        // console.log(this.fd);
        if (typeof this.fd !== 'number') { // 如果是异步的方式则直接执行后面的代码，否则等待open方法执行后再执行
            return this.once('open', this.read)
        }
        let buf = Buffer.alloc(this.highWaterMark)

        let howMuchToRead = this.end
            ? Math.min(this.end - this.readOffset, this.highWaterMark)
            : this.highWaterMark


        fs.read(this.fd, buf, 0, howMuchToRead, this.readOffset, (err, readBytes) => {
            if (readBytes) { // 如果读取成功
                this.readOffset += readBytes
                this.emit('data', buf.slice(0, readBytes))
                this.read()
            } else {
                this.emit('end')
                this.close()
            }
        })
    }
    close() {
        fs.close(this.fd, (err) => {
            this.emit('close')
        })
    }

}

let rs = new MyFileReadStream('test.txt', { highWaterMark: 3, end: 7 })
// rs.on('open', (fd) => {
//     console.log('open', fd)
// })
// rs.on('error', (err) => {
//     console.log('error', err)
// })

rs.on('data', (chunk) => {
    console.log('chunk:', chunk);
})

rs.on('close', () => {
    console.log('close:');
})
rs.on('end', () => {
    console.log('end:');
})

console.log(Buffer);
